%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% CS221 Programming Assignment 2
%%   Olga Russakovsky, Oct. 2009
%%   Stanford University
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% CS221 TODO: Modify as needed to switch between 1k and 10k examples

%[DataSet, DataTestSet] = loadData('training3costs.txt');
[DataSet, DataTestSet] = loadData('trainingzillionnolegscosts.txt');

%col1 = DataSet.x(:,1);
%DataSet.x(:,1)=DataSet.x(:,2);
%DataSet.x(:,2)=col1;

DataSet.numThresholds = 10;
DataTestSet.numThresholds = 10;

DataSet.thresholds = findThresholdsBuckets(DataSet); % size T*N : 1 list of thresholds per feature


if (DataSet.numFeatures ~= DataTestSet.numFeatures)
   error(sprintf('The test and training data dont have the same number of features. Test : %d, Training : %d',DataTestSet.numFeatures, DataSet.numFeatures)); 
end
    
% Train and evaluate the tree at multiple depths
%depths = 4:2:14;  % 4, 6, 8, 10, 12, 14
maxdepth = 4;
depths = 1:maxdepth;
trainingAccuracies = [];
testSetAccuracies = [];

% CS221 Debugging
% ---------------
% After you implement the 4 required functions for part (a), uncomment
% the following 4 lines and run pa2_matlab_a. Make sure the trainingImages
% and trainingLabels above are set to use 1k examples, not 10k. 
  %  depths = 1:3;
  %  DigitSet.pixels = DigitSet.pixels(1:100, :);
  %  DigitSet.labels = DigitSet.labels(1:100);
  %  DigitSet.weights = DigitSet.weights(1:100);
% Your output should be:
%   Loading 1000 digits
%   Loading 1000 digits
%   Training trees of depth 1...
%   Testing...
%    ... training set accuracy of 0.450000
%    ... test set accuracy of 0.356000
%   Training trees of depth 2...
%   Testing...
%    ... training set accuracy of 0.780000
%    ... test set accuracy of 0.441000
%   Training trees of depth 3...
%   Testing...
%    ... training set accuracy of 0.940000
%    ... test set accuracy of 0.512000

tic
for depth = depths
    % Training code
    disp(sprintf('Training trees of depth %i...', depth));
    DecisionTree = growDecisionTree([], DataSet, depth);

    % Testing code
    for i = 1:length(DecisionTree)
        disp(sprintf('Node %3i: %3i %4.4f %3i %3i %3i %3i', i, ...
            DecisionTree(i).featureNum, ...
            DecisionTree(i).threshold, ...
            DecisionTree(i).leftChild, ...
            DecisionTree(i).rightChild, ...
            DecisionTree(i).positiveCount, ...
            DecisionTree(i).totalCount));
    end 
    disp('Testing...');
    acc = decisionTreeAccuracy(DecisionTree, DataSet);
    disp(sprintf(' ... training set accuracy of %f', acc));
    trainingAccuracies = [trainingAccuracies acc];
    
    acc = decisionTreeAccuracy(DecisionTree, DataTestSet);
    disp(sprintf(' ... test set accuracy of %f', acc));
    testSetAccuracies = [testSetAccuracies acc];
end
toc

% Plotting code
figure;
plot(depths, trainingAccuracies, 'b.--', 'MarkerSize', 30, 'LineWidth', 2);
hold on;
plot(depths, testSetAccuracies, 'r*--', 'MarkerSize', 30, 'LineWidth', 2);
ylim([0 1]);
figureTitle = sprintf('Training on %d examples', DataSet.numExamples);
title(figureTitle);
xlabel('Tree depth');
ylabel('Accuracy');
legend('Training set accuracy', 'Test set accuracy', 'location', 'East');
hold off;

writeTreeToFile(DecisionTree, DataSet,'tree.txt');
